/*
 * Copyright (C) 2013 Daniel Wasilew <daniel.wasilew@codeminer.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.codeminer.parts.specification.html;

import de.wusel.picotask.xml.attributes.SimpleAttributes;
import de.wusel.picotask.xml.element.XMLElement;
import org.codeminer.parts.specification.general.FilePart;

import java.io.PrintWriter;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * User: Daniel Wasilew <daniel.wasilew@codeminer.org>
 * Date: 03.03.13
 * Time: 09:38
 */
public class ActionHTMLPart implements FilePart {
    @Override
    public void writeTo(PrintWriter writer, XMLElement parsedElement) {
        String actionName = parsedElement.getChild("class").getAttributes().getString("name");
        XMLElement descriptionElement = parsedElement.getChild("description");
        String classDescription = descriptionElement != null ? descriptionElement.getValue() : "";
        String permissions = getPermissions(parsedElement);
        XMLElement inputElement = parsedElement.getChild("input");
        List<XMLElement> inputChildren = inputElement!= null ? inputElement.getChildren("param") : Collections.<XMLElement>emptyList();

        StringBuilder partBuilder = new StringBuilder();
        partBuilder.append("    <div class=\"row-fluid\">\n");
        partBuilder.append("        <div class=\"span12\">\n");
        partBuilder.append("            <h2>Action</h2>\n");
        partBuilder.append("            <p>Name: <span class=\"label label-info\">").append(actionName).append("</span></p>\n");
        partBuilder.append("            <p>Description: <span class=\"label label-info\">").append(classDescription).append("</span></p>\n");
        partBuilder.append("            <p>Permissions: <span class=\"label label-info\">").append(permissions).append("</span></p>\n");
        partBuilder.append("            Parameters:\n");
        partBuilder.append("            <table class=\"table table-bordered table-hover table-striped\">\n");
        partBuilder.append("                <tr>\n");
        partBuilder.append("                    <th>Name</th>\n");
        partBuilder.append("                    <th>Type</th>\n");
        partBuilder.append("                    <th>Values</th>\n");
        partBuilder.append("                </tr>\n");
        partBuilder.append("                <tr>\n");
        partBuilder.append("                    <td>actionName</td>\n");
        partBuilder.append("                    <td>String</td>\n");
        partBuilder.append("                    <td>").append(actionName).append("</td>\n");
        partBuilder.append("                </tr>\n");

        for (XMLElement inputChild : inputChildren) {
            SimpleAttributes attributes = inputChild.getAttributes();
            String name = attributes.getString("name");
            String type = attributes.getString("type");
            String description = attributes.contains("description") ? attributes.getString("description") : "";

            partBuilder.append("                <tr>\n");
            partBuilder.append("                    <td>").append(name).append("</td>\n");
            partBuilder.append("                    <td>").append(type).append("</td>\n");
            partBuilder.append("                    <td>").append(description).append("</td>\n");
            partBuilder.append("                </tr>\n");
        }

        partBuilder.append("            </table>\n");
        partBuilder.append("            <h3>Request:</h3>\n");
        partBuilder.append("                    <pre>{\n");
        partBuilder.append("actionName").append(" : ").append(actionName).append("\n");
        for (XMLElement inputChild : inputChildren) {
            SimpleAttributes attributes = inputChild.getAttributes();
            String name = attributes.getString("name");
            String example = attributes.contains("example") ? attributes.getString("example") : "";
            partBuilder.append(name).append(" : ").append(example).append("\n");
        }

        partBuilder.append("}</pre>\n");
        partBuilder.append("            <h3>Responses:</h3>\n");


        List<XMLElement> response = parsedElement.getChildren("response");
        for (XMLElement xmlElement : response) {
            XMLElement responseDescriptionChild = xmlElement.getChild("description");
            String resultValue = xmlElement.getChild("result").getAttributes().getString("value");
            String resultType = xmlElement.getChild("type").getAttributes().getString("value");

            String description = responseDescriptionChild != null ? responseDescriptionChild.getValue() : "";
            partBuilder.append("            <h4>").append(description).append("</h4>\n");
            partBuilder.append("                    <pre>{\n");
            partBuilder.append("type : ").append(resultType).append("\n");

            addParamValues(partBuilder, xmlElement);
            addFixedValues(partBuilder, xmlElement);

            partBuilder.append("}</pre>\n");
        }
        partBuilder.append("        </div>\n");
        partBuilder.append("    </div>");

        writer.print(partBuilder.toString());
    }

    private void addParamValues(StringBuilder partBuilder, XMLElement xmlElement) {
        List<XMLElement> param = xmlElement.getChildren("param");
        for (XMLElement element : param) {
            SimpleAttributes attributes = element.getAttributes();
            String name = attributes.getString("value");
            String value = attributes.contains("example") ? attributes.getString("example") : "";
            partBuilder.append(name).append(" : ").append(value).append("\n");
        }
    }

    private void addFixedValues(StringBuilder partBuilder, XMLElement xmlElement) {
        List<XMLElement> param = xmlElement.getChildren("fixed");
        for (XMLElement element : param) {
            SimpleAttributes attributes = element.getAttributes();
            String key = attributes.getString("key");
            String value = attributes.getString("value");
            partBuilder.append(key).append(" : ").append(value).append("\n");
        }
    }

    private String getPermissions(XMLElement parsedElement) {
        XMLElement permissionsElement = parsedElement.getChild("permissions");
        String permissions = "";
        if (permissionsElement != null) {
            List<String> permissionsValue = new LinkedList<>();
            List<XMLElement> permission = permissionsElement.getChildren("permission");
            for (XMLElement xmlElement : permission) {
                permissionsValue.add(xmlElement.getValue());
            }
            if (permissionsValue.isEmpty()) {
                permissions = "No permissions required";
            } else {
                Iterator<String> iterator = permissionsValue.iterator();
                while (iterator.hasNext()) {
                    permissions += iterator.next();
                    if (iterator.hasNext()) {
                        permissions += ", ";
                    }
                }
            }

        } else {
            permissions = "No permissions required";
        }
        return permissions;
    }
}
